package cn.wyj.basic.service.impl;

import cn.wyj.basic.config.BussinessException;
import cn.wyj.basic.constant.BaseContant;
import cn.wyj.basic.deo.PhoneSmsCodeDto;
import cn.wyj.basic.service.IVerifyCodeService;
import cn.wyj.basic.util.SendSmsUtils;
import cn.wyj.basic.util.StrUtils;
import cn.wyj.basic.util.VerifyCodeUtils;
import cn.wyj.user.domain.User;
import cn.wyj.user.mapper.LogininfoMapper;
import cn.wyj.user.mapper.UserMapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.concurrent.TimeUnit;

@Service
@Slf4j
public class VerifyCodeControllerImpl implements IVerifyCodeService {

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private LogininfoMapper logininfoMapper;

    @Override
    public String getImageCode(String uuidKey) {
        // 生成随机数
        String randomCode = StrUtils.getComplexRandomString(4);
        // 存入到reids
        redisTemplate.opsForValue().set(uuidKey,randomCode,3, TimeUnit.MINUTES);
        // 生成图形验证码返回给前端
        return VerifyCodeUtils.VerifyCode(100, 35, randomCode);
    }

    /**
     * 发送手机验证码
     * @param dto
     */
    @Override
    public void smsCode(PhoneSmsCodeDto dto) {

        // 短信验证码发送，有两个，一个是手机号注册，一个是微信登录的手机号绑定
        if ("register".equals(dto.getType())){
            // 验证参数是否为空,在实体里面用注解处理
            // 手机号格式

            // 图形验证码是否正确
            verifyImgageCode(dto);
            // 发送短信验证码
            sendSmsCode(String.format(BaseContant.VerfityCodeCons.REGISTER_SMSCODE_PHONE,dto.getPhone()));

        } else if ("binder".equals(dto.getType())){
            // 发送短信验证码
            sendSmsCode(String.format(BaseContant.VerfityCodeCons.BINDER_SMSCODE_PHONE,dto.getPhone()));
        }

    }

    private void sendSmsCode(String redisKey) {
        // 两次发送时间间隔是否大于60s
        String redisSmsCode = (String) redisTemplate.opsForValue().get(redisKey);
        String smsCode = "";
        if (StringUtils.isNotBlank(redisSmsCode)){
            // 不为空才做 60s 校验 redisSmsCode存的是   验证码：时间戳\

            //

            String[] split = redisSmsCode.split(":");
            smsCode = split[0];
            // 当前时间
            long newTime = System.currentTimeMillis();
            // redis中的时间
            Long oldTime = Long.valueOf(split[1]);
            if (newTime - oldTime < 60 * 1000){
                throw new BussinessException("滚去登录");
            }
        }else {
            // 如果，为空了，就是需要验证码

            // 用工具类生成验证码
            smsCode = StrUtils.getRandomString(4);
        }
        log.info("验证码为:{}", smsCode);
        // 将验证码，后面加上时间，作为value存入redis，它的Key是常量，加上电话号码   register:smscode:%s
        String redisValue = smsCode + ":" + System.currentTimeMillis();
        // 存入到redis
        redisTemplate.opsForValue().set(redisKey, redisValue, 5 , TimeUnit.MINUTES);
        // 发送短消息
//        SendSmsUtils.send(dto.getPhone(),"你好：你的验证码为：" + smsCode + "，5分钟内有效！");


        // 是否需要重置验证码
    }

    private void verifyImgageCode(PhoneSmsCodeDto dto) {
        // 先从redis中取值，dto是封装的前端参数实体,可以从中取到uuid，再取到redis中以uuid为key的value，也就是图片验证码的数字
        String imageCode = (String) redisTemplate.opsForValue().get(dto.getImageCodeKey());
        // 判断取到的图片验证码数字是否为空，这个是从redis中取到的，不是空，接着判断和前端传入的图形验证码，这个是用户填写的
        if (StringUtils.isBlank(imageCode) || !imageCode.equalsIgnoreCase(dto.getImageCodeValue())){
            throw new BussinessException("验证码错误");
        }
        // 当前手机号是否已经注册
        // 首先查询user表，根据phone去查，如果为空，就是没有注册过
        User user = userMapper.findByPhone(dto.getPhone());
        if (null != user){
            throw new BussinessException("手机号已注册，请登录");
        }
    }
}
